//-----------------------------------------------------------------------------
// F3xx_USB_Main.c
//-----------------------------------------------------------------------------
// Copyright 2005 Silicon Laboratories, Inc.
// http://www.silabs.com
//
// Program Description:
//
// This application will communicate with a PC across the USB interface.
// The device will appear to be a mouse, and will manipulate the cursor
// on screen.
//
// How To Test:    See Readme.txt
//
//
// FID:            
// Target:         C8051F3xx
// Tool chain:     Keil / Raisonance
//                 Silicon Laboratories IDE version 2.6
// Command Line:   See Readme.txt
// Project Name:   F3xx_FirmwareTemplate
//
// Release 1.1
//    - Minor changes to F3xx_USB0_Descriptor.c
//    - 16 NOV 2006
// Release 1.0
//    -Initial Revision (PD)
//    -07 DEC 2005
//
//-----------------------------------------------------------------------------
// Header Files
//-----------------------------------------------------------------------------

#include "c8051f3xx.h"
#include "F3xx_USB0_Register.h"
//#include "F3xx_USB0_CustomApp.h"
#include "F3xx_USB0_InterruptServiceRoutine.h"
#include "F3xx_USB0_Descriptor.h"
#include "marquee_isr.h"

//-----------------------------------------------------------------------------
// Definitions
//-----------------------------------------------------------------------------

#include "compiler_defs.h"
//#include "C8051F380_defs.h"

// Peripheral specific initialization functions,
// Called from the Init_Device() function
void SPI_Init()
{
    SPI0CN    = 0x01;	// Enable SPI in 3 wire mode
	SPI0CFG	  = 0x80;	// Enable master mode
}

void Port_IO_Init()
{
	// Unused pins
    // P0.0  -  Unused	
    // P0.1  -  Unused

	// SPI interface pins
    // P0.2  -  SCK  (SPI0)
    // P0.3  -  MISO (SPI0)
    // P0.4  -  MOSI (SPI0)
    // P0.5  -  LED Matrices chip enable
    // P0.6  -  Memory chip enable

	// LED Matrix pins
    // P0.7  -  LED Matrix Row enable 0
    // P1.0  -  LED Matrix Row enable 1
    // P1.1  -  LED Matrix Row enable 2
    // P1.2  -  LED Matrix Row enable 3
    // P1.3  -  LED Matrix Row enable 4
    // P1.4  -  LED Matrix Row enable 5
    // P1.5  -  LED Matrix Row enable 6
    // P1.6  -  LED Matrix Row enable 7

	// User control pins
    // P1.7  -  Button 0
    // P2.0  -  Button 1
    // P2.1  -  Button 2

	// Control LCD pins
    // P2.2  -  Control LCD Pin RS
    // P2.3  -  Control LCD Pin LE
    // P2.4  -  Control LCD Pin DB4
    // P2.5  -  Control LCD Pin DB5
    // P2.6  -  Control LCD Pin DB6
    // P2.7  -  Control LCD Pin DB7

	// Unused (Used by programming interface only)
    // P3.0  -  Unused

    P0MDOUT   = 0xFF;
    P1MDOUT   = 0xFF;
    P2MDOUT   = 0xFF;
    P3MDOUT   = 0x01;
    P0SKIP    = 0xE3;
    P1SKIP    = 0xFF;
    P2SKIP    = 0xFF;
    P3SKIP    = 0x01;
    XBR0      = 0x02;
    XBR1      = 0x40;
}

void Oscillator_Init()
{
    FLSCL     = 0x90;
    CLKSEL    = 0x03;
    OSCICN    = 0xC3;
}

void Interrupts_Init()
{
    EIE1      = 0x82;	// Enable USB and Timer 3 interrupts
    IE        = 0xA8;	// Enable all interrupts and Timer 1 and 0
}

// Initialization function for device,
// Call Init_Device() from your main program
void Init_Device(void)
{
    SPI_Init();
    Port_IO_Init();
    Oscillator_Init();
    Interrupts_Init();
}

void USB_Init (void)
{
   POLL_WRITE_BYTE (POWER, 0x08);      // Force Asynchronous USB Reset
   POLL_WRITE_BYTE (IN1IE, 0x07);      // Enable Endpoint 0-1 in interrupts
   POLL_WRITE_BYTE (OUT1IE,0x07);      // Enable Endpoint 0-1 out interrupts
   POLL_WRITE_BYTE (CMIE, 0x07);       // Enable Reset, Resume, and Suspend
                                       // interrupts
   USB0XCN = 0xE0;                     // Enable transceiver; select full speed
   POLL_WRITE_BYTE (CLKREC,0x8F);      // Enable clock recovery, single-step
                                       // mode disabled
	IE |= 0x20;		// Enable Timer 2 interrupt

									   
                                       // Enable USB0 by clearing the USB
   POLL_WRITE_BYTE (POWER, 0x01);      // Inhibit Bit and enable suspend
                                       // detection
}

void Timer_Setup(void)
{
	// Timer for refresh rate
	// Using Timer 2
	CKCON |= 0x58;	// Enable Timers 1,2,3 to use system clock
	TMOD  |= 0x20;	// Enable Timer 1 in 8 bit auto-reload mode 
	TMR2CN = 0x04;	// Enable Timer 2 in 16 bit auto-reload mode
	TMR3CN = 0x0C;	// Enable Timer 3 in 8 bit auto-reload mode
	// Set timer 2 reload value to 40537 to overflow at 480 Hz
	// 60 Hz screen refresh * 8 rows
	TMR2RLL = 0x59;
	TMR2RLH = 0x9E;
	// Timer 1 value
	// SPI clock is set to SYSCLK/2, and we need an interrupt every 8 SPI clocks
	// Which means we need to set the reload value to 256-16
	TH1 = 0xF0;	// 240
	// Timer 3 reload value - using only high byte for 8 bit counter
	TMR3RLH = 0xA0; // 160 every 2 micro seconds
	
}

//-----------------------------------------------------------------------------
// Main Routine
//-----------------------------------------------------------------------------
void main(void)
{
   PCA0MD &= ~0x40;
   SP = 0x80;

   SPI_Init();
   Port_IO_Init();
   Oscillator_Init();
   Interrupts_Init();
   USB_Init ();

   Timer_Setup();
   Init_Ticks();	// Set up ISR to count using the timer
	
   EA = 1;

   P0 |= 0x40;		// Start flash memory with chip enable high
   while (1)
   {
   }
}